home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / ticomm.arc / TICOM.ASM next >
Encoding:
Assembly Source File  |  1987-05-21  |  18.7 KB  |  538 lines

  1.        PAGE  ,132
  2. ;*******************************************************************************
  3. ;*                                                                             *
  4. ;*     SYNC?/ASYNCHRONOUS COMMUNICATIONS FOR THE TI-PROFESSIONAL COMPUTER      *
  5. ;*      REV LEVEL 1.0                                                          *
  6. ;*      WRITTEN AND PLACED IN THE PUBLIC DOMAIN BY:                            *
  7. ;*                                                                             *
  8. ;*                                            DAN MAUS                         *
  9. ;*                                            16737 ANNA TRAIL S.E.            *
  10. ;*                                            PRIOR LAKE, MN 55372             *
  11. ;*                                                                             *
  12. ;* MANY THANKS TO: TEXAS INSTRUMENTS, EDEN PRAIRIE MN.                         *
  13. ;*                 ARROW ELECTRONICS, EDINA MN.                                *
  14. ;*                 COMPUTER LAW SYSTEMS, EDEN PRAIRIE MN.                      *
  15. ;*                                                                             *
  16. ;* You can find Dan Maus and other programmers on Terrapin Station dBBS!       *
  17. ;* 612/623-0152   24 hours - 2400/1200                                         *
  18. ;*******************************************************************************
  19. CODE    SEGMENT PUBLIC
  20.         ASSUME CS:CODE,DS:CODE,ES:CODE
  21.         JMP START
  22. ; SOME EQUATES AND USAGE CONVENTIONS
  23.  
  24. SVCINT  EQU     70H ; INTERRUPT USED BY APPLICATION
  25.                     ;    FUNC
  26.                     ;  NOTE ONLY PORT1 IS CURRENTLY SUPPORTED
  27.                     ; AH = 1 - OPEN/CHANGE COMMUNICATIONS
  28.                     ;          AL = PORT (1-4)
  29.                     ;          CURRENTLY PARAMETERS ARE STORED
  30.                     ;          IN THIS ROUTINE, HOWEVER A FUTURE
  31.                     ;          ENHANCEMENT WILL ALLOW EXTERNAL TABLES
  32.                     ;
  33.                     ;
  34.                     ;          STATUS RETURNED IN AL
  35.                     ;          0 = PORT OPENED
  36.                     ;         -1 = NON EXISTENT PORT, OR HARDWARE
  37.                     ;              INCOMPATIBILITY.
  38.                     ;
  39.                     ; AH = 2   READ COMMUNICATION STATUS
  40.                     ;          AL = PORT (1-4)
  41.                     ;          STATUS RETURNED IN AL
  42.                     ;          0 = READY <->
  43.                     ;          1 = DATA IN RECV BUFFER
  44.                     ;          2 = RECV BUFFER OVERFLOW
  45.                     ;
  46.                     ; AH = 3   READ CHARACTER FROM FIFO BUFFER
  47.                     ;          AL = PORT
  48.                     ;          CHAR RETURNED IN AL
  49.                     ;          CHECK FNC 2 BEFORE CALLING
  50.                     ;          RETURNS 0 IF NO CHAR READY
  51.                     ;
  52.                     ; AH = 4   WRITE CHARACTER
  53.                     ;          AL = PORT
  54.                     ;          DL = CHAR
  55.                     ;
  56.                     ; AH = 5   ISSUE BREAK
  57.                     ;          AL = PORT
  58.                     ;
  59.                     ; AH = 6   CLOSE COMMUNICATIONS
  60.                     ;          AL = PORT
  61.                     ;
  62.                     ; AH = 7   PURGE INPUT BUFFER
  63.                     ;          AL = PORT
  64.                     ;
  65.  
  66.                     ;
  67. COMINT  EQU 40H     ; 8530 INTERRUPT
  68.                     ; GENERATED BY ASYNC BOARD.
  69.                     ; DO NOT USE THIS FROM AN APPLICATION.
  70.                     ;
  71. PARTBL:             ; OPEN COMMUNICATIONS STRUCTURE
  72. ; ASYNC BAUD RATES BASED ON 4.9152 MHZ CLOCK
  73. BR300   EQU 54
  74. BR1200  EQU 62
  75. BR2400  EQU 30
  76. BR4800  EQU 14
  77. BR9600  EQU 6
  78. BR192   EQU 2
  79.  
  80. BAUDR   DW BR9600   ; BAUD RATE BYTE NOTE:USED IN BYTES (H/L)
  81.                     ;                     WHEN SENT TO 8530
  82. RBITS   DB 8        ; NUMBER OF READ DATA BITS  (5-8)
  83. TBITS   DB 8        ; NUMBER OF WRITE DATA BITS (5-8)
  84. SBITS   DB 1        ; NUMBER OF STOP BITS       0 = SYNCRONOUS OPERATION
  85.                                              ;      (SEE 8530 TECH SPECS)
  86.                                              ;  1 = 1 BIT
  87.                                              ;  2 = 1-1/2 BITS
  88.                                              ;  3 = 2 BITS
  89. PBITS   DB 0        ; PARITY 0 = NO, 1 = EVEN, 3 = ODD
  90. TESTRES:            ; OFFSET CHECKED TO VALIDATE RESIDENCY
  91. NPORTS  EQU 1       ; NUMBER OF PORTS IN SYSTEM
  92. RXINTEN EQU 20H     ; ENABLE INTERRUPT ON NEXT RX CHAR    (WR0)
  93. BREAK   EQU 10H     ; ENABLE BREAK SIGNAL                 (WR5)
  94. RESET   EQU 0C0H    ; RESET 8530
  95. COMNLEN EQU 80H     ; COMMAND LINE PARAMETER LENGTH
  96. ;*********************** DATA AREA ****************************
  97. SVCOLD  DD  ; OLD INTERRUPT VECTOR FOR COM SVC
  98. COMOLD  DD  ; "         "      "    "  8530 INTERRUPT
  99.  
  100. CINT    DW   0
  101. ACOM    DW   0
  102. ADAT    DW   0
  103. BCOM    DW   0
  104. INADR   DW   0  ; CURRENT BUFFER ADDRESS USED BY 8530 ISR
  105. SVADR   DW   0  ; CURRENT BUFFER ADR USED BY SVC ROUTINE
  106. BUFCNT  DW   0  ; CURRENT BYTE COUNT IN BUFFER
  107. TXREG   DB   0
  108.  
  109. ;************************** SVC INTERRUPT SERVICE ROUTINE ********************
  110. ;
  111. SVCISR:
  112.         STI         ; IMMEDIATELY REENABLE INTERRUPTS
  113.         PUSH    AX  ; NOTE APPLICATION MUST SUPPLY SUFFICIENT STACK
  114.         PUSH    BX
  115.         PUSH    CX
  116.         PUSH    DX
  117.         PUSH    SI
  118.         PUSH    DI
  119.         PUSH    CS
  120.         POP     DS ; SET UP OUR CS AS OUR DS
  121.         CMP     AH,7
  122.         JG      INVFC
  123.         CMP     AH,1
  124.         JL      INVFC
  125. PORTS:                ; SET UP CORRECT PORT IDS (CINT ACOM ADAT BCOM)
  126.         CMP     AL,NPORTS
  127.         JG      BADPRT
  128.         DEC     AL
  129.         JC      INVPORT
  130.         SHL     AL,1
  131.         SHL     AL,1
  132.         SHL     AL,1
  133.         PUSH    AX
  134.         XOR     AH,AH
  135. PORT1   EQU     0E0H
  136.         ADD     AL,PORT1
  137.         MOV     CINT,AX     ; SAVE INTERRUPT ACKNOWLEDGE PORT
  138.         ADD     AL,4
  139.         MOV     BCOM,AX     ; SAVE CHANNEL B COMMAND PORT
  140.         INC     AL
  141.         INC     AL          ; SKIP CHANNEL B DATA (UNUSED)
  142.         MOV     ACOM,AX     ; SAVE CHANNEL A COMMAND PORT
  143.         INC     AL
  144.         MOV     ADAT,AX     ; SAVE CHANNEL A DATA PORT
  145.         POP     AX
  146.         XOR     AL,AL
  147.         XCHG    AH,AL
  148.         MOV     SI,AX
  149.         SHL     SI,1
  150.         JMP     WORD PTR CS:[JTBL+SI]
  151. JTBL    DW      0  ; DUMY
  152.         DW      OPEN
  153.         DW      STAT
  154.         DW      READ
  155.         DW      WRITE
  156.         DW      BRAAK
  157.         DW      CLOSE
  158.         DW      PURGE
  159. INVFC:
  160. INVPORT:
  161. BADPRT:
  162.         MOV     AX,-1  ; SET BAD STATUS & RETURN
  163. COMEXIT:              ; SVC CALL EXIT
  164.         PUSH    ES
  165.         POP     DS
  166.         POP     DI
  167.         POP     SI
  168.         POP     DX
  169.         POP     CX
  170.         POP     BX
  171.         POP     [TRASH] ; DISCARD OLD AX, KEEP OURS
  172.         IRET        ; RETURN TO SVC CALLER
  173. TRASH   DW      0
  174. ;************************* OPEN PORT ***************************
  175. OPEN:   ; OPEN COMMUNICATION PORT IN AL
  176.         MOV     DX,ACOM   ; LOAD A COMMAND PORT
  177.         MOV     AL,9      ; SELECT WR 9
  178.         OUT     DX,AL
  179.         MOV     AL,RESET  ; RESET 8530
  180.         OUT     DX,AL
  181.         MOV     AL,11     ; SELECT WR 11
  182.         OUT     DX,AL
  183. WR11CTL EQU     52H       ; SET RX CLOCK=BR GENERATOR
  184.                           ; SET TX CLOCK=BR GENERATOR
  185.         MOV     AL,WR11CTL
  186.         OUT     DX,AL
  187.         MOV     AL,14    ; ENABLE BR GENERATOR
  188.         OUT     DX,AL
  189.         MOV     AL,3
  190.         OUT     DX,AL
  191.         MOV     AL,12     ; SEL WR 12
  192.         OUT     DX,AL
  193.         MOV     AL,BYTE PTR[BAUDR]   ; OUTPUT LOW ORDER BAUD RATE
  194.         OUT     DX,AL
  195.         MOV     AL,13     ; SEL WR 13
  196.         OUT     DX,AL
  197.         MOV     AL,BYTE PTR[BAUDR+1] ; OUTPUT HIGH ORDER BYTE
  198.         OUT     DX,AL
  199.         MOV     AL,2      ; WR2 VECTOR REGISTER
  200.         OUT     DX,AL
  201.         MOV     AL,COMINT
  202.         OUT     DX,AL     ; SET 8530 INTERRUPT VECTOR
  203.         MOV     AL,15     ; WR15
  204.         OUT     DX,AL
  205.         MOV     AL,0      ; NO EXTERNAL STATUS INTERRUPTS
  206.         OUT     DX,AL     ;
  207.         MOV     AL,1      ; WR1
  208.         OUT     DX,AL
  209.         MOV     AL,10H    ; INT ON ALL RX CHARS & SP COND
  210.         OUT     DX,AL
  211.         MOV     AL,5      ; WR 5
  212.         OUT     DX,AL
  213.         XOR     AX,AX
  214.         MOV     AL,TBITS
  215.         SUB     AL,5      ;
  216.         ROR     AX,1
  217.         ROR     AL,1
  218.         ROR     AL,1      ; SWAP 2 BITS SEE 8530 TR
  219.         ROL     AX,1
  220.         ROR     AL,1
  221.         ROR     AL,1      ; POSITION TX BITS
  222.         OR      AL,8AH    ; ENABLE DTR RTS  TX
  223.         MOV     TXREG,AL
  224.         OUT     DX,AL
  225.         MOV     AL,3      ; WR3
  226.         OUT     DX,AL
  227.         XOR     AX,AX
  228.         MOV     AL,RBITS  ; SET RECIEVE BITS ENABLE RECIEVE
  229.         SUB     AL,5
  230.         ROR     AX,1
  231.         ROR     AL,1
  232.         ROR     AL,1
  233.         ROL     AX,1
  234.         ROR     AL,1
  235.         OR      AL,1  ; SET RX ENABLE
  236.         OUT     DX,AL
  237.         MOV     AL,4
  238.         OUT     DX,AL
  239.         MOV     AL,SBITS
  240.         SHL     AL,1
  241.         SHL     AL,1
  242.         OR      AL,PBITS  ; SET PARITY BITS
  243.         OR      AL,40H    ; SET  X16 CLOCK MODE
  244.         OUT     DX,AL
  245.         MOV     DX,BCOM   ; B COMMAND PORT
  246.         MOV     AL,15
  247.         OUT     DX,AL
  248.         MOV     AL,0      ; NO EXT STS INT'S
  249.         OUT     DX,AL
  250.         MOV     AL,1
  251.         OUT     DX,AL
  252.         MOV     AL,10H    ; INT ON ALL RX CHAR
  253.         OUT     DX,AL     ; PORT IS NOW OPEN
  254.         MOV     AX,OFFSET INBUF
  255.         MOV     SVADR,AX
  256.         MOV     INADR,AX
  257.         XOR     AX,AX
  258.         MOV     BUFCNT,AX
  259.         MOV     DX,ACOM
  260.         MOV     AL,9
  261.         OUT     DX,AL
  262.         MOV     AL,8H    ; ENABLE RECIEVE INTERRUPTS
  263.         OUT     DX,AL
  264.         MOV     DX,BCOM
  265.         MOV     AL,9
  266.         OUT     DX,AL
  267.         MOV     AL,8H
  268.         OUT     DX,AL
  269.         MOV     AL,36H
  270.         OUT     19H,AL     ; SET 8259 ENABLE  COM1
  271.         JMP     COMEXIT
  272. ;************************ STATUS ROUTINE ********************
  273. STAT:
  274.         XOR     AX,AX
  275.         MOV     CX,BUFCNT
  276.         JCXZ    SDONE
  277.         MOV     AL,1    ; SET DATA IN BUFFER
  278.         CMP     CX,0
  279.         JG      SDONE
  280.         INC     AL      ; IF DATALEN < 0 THEN BUF OVERFLOW
  281. SDONE:  JMP     COMEXIT
  282. ;*********************** OBTAIN CHAR FROM CIRC BUFFER **************
  283. ;
  284. ; NOTE: READ BUFFER STRATEGY MUST BE MODIFIED TO IMPLEMENT MULTI-PORT
  285. ;       OPERATION.
  286. ;
  287. READ:   MOV     AX,BUFCNT
  288.         CMP     AX,0
  289.         JE      NOCHARS
  290.         DEC     BUFCNT   ; REDUCE NUMBER OF CHARS IN BUFFER
  291.         MOV     SI,SVADR ; GET OUR CURRENT ADR IN BUFFER
  292.         MOV     AL,BYTE PTR[SI] ; GET CHARACTER
  293.         INC     SI
  294.         CMP     SI,OFFSET LADR  ; AT LAST ADDR ?
  295.         JNE     CONT
  296.         MOV     SI,OFFSET INBUF
  297. CONT:   MOV     SVADR,SI ; SAVE CURRENT INPUT BUFFER ADDRESS
  298. NOCHARS:JMP     COMEXIT  ; CHAR SHOULD BE IN AL
  299. ;************************ WRITE CHAR IN DL **************************
  300. ;
  301. WRITE:
  302.         MOV     AH,DL
  303.         MOV     DX,ACOM
  304. TXIP:   IN      AL,DX    ; DONT TRANSMIT IF ALREADY TRANSMITTING
  305.         AND     AL,4
  306.         JZ      TXIP
  307.         MOV     DX,ADAT
  308.         MOV     AL,AH
  309.         OUT     DX,AL    ; OUTPUT CHAR
  310.         XOR     AX,AX
  311.         JMP     COMEXIT
  312. ;***************** ISSUE BREAK ***********************
  313. BRAAK:
  314.         MOV     AL,5 ; WR5
  315.         MOV     DX,ACOM
  316.         OUT     DX,AL
  317.         MOV     AL,0FAH   ; BREAK ENABLE BIT
  318.         OUT     DX,AL
  319.         MOV     CX,7F00H ; WAIT A WHILE
  320. WAITX:
  321.         PUSH CX
  322.         NOP
  323.         POP  CX
  324.         LOOP    WAITX
  325.         MOV     AL,0EAH ; DISABLE BREAK BIT
  326.         PUSH    AX
  327.         MOV     AL,5
  328.         OUT     DX,AL   ; WR5
  329.         POP     AX
  330.         OUT     DX,AL   ; KILL BREAK
  331.         JMP     COMEXIT
  332. ;********************* CLOSE PORT ***********************
  333. CLOSE:
  334.         MOV    DX,ACOM
  335.         MOV    AL,9 ; WR9
  336.         OUT    DX,AL
  337.         MOV    AL,RESET
  338.         OUT    DX,AL
  339.         MOV    AL,37H
  340.         OUT    19H,AL  ; DISABLE 8259 IR0
  341.         JMP    COMEXIT
  342. ;********************* BUFFER PURGE **********************
  343. PURGE:
  344.         XOR    AX,AX
  345.         MOV    BUFCNT,AX
  346.         MOV    AX,OFFSET INBUF
  347.         MOV    SVADR,AX
  348.         MOV    INADR,AX
  349.         JMP    COMEXIT
  350. ;************************** END OF SVC SERVICE CODE *********************
  351. ;******************** START OF 8530 INTERRUPT SERVICE CODE ***************
  352. DSADDR  EQU 180H
  353. INTCTR  EQU 19AH
  354. STKSAV  DW  0
  355.         DW  0
  356.         DW  50 DUP(0) ; RESERVE SOME INTERNAL STACK
  357. INTSTK  LABEL WORD
  358. ERRST   DW  0
  359. COMISR:                 ; INTERRUPTS DISABLED THROUGHOUT
  360.         PUSH   DS
  361.         CLI
  362.         MOV    CS:STKSAV+2,SS
  363.         MOV    CS:STKSAV,SP
  364.         MOV    SP,CS
  365.         MOV    SS,SP
  366.         MOV    SP,OFFSET INTSTK
  367.         PUSH   AX
  368.         XOR    AX,AX
  369.         MOV    DS,AX
  370.         INC    DS:BYTE PTR[INTCTR]  ; ADD 1 TO INTERRUPT COUNT
  371.         PUSH   BX
  372.         PUSH   CX
  373.         PUSH   DX
  374.         PUSH   CS
  375.         POP    DS
  376. NEXT:   MOV    DX,CINT  ; INTERRUPT ACKNOWLEDGE PORT
  377.         MOV    AL,0
  378.         OUT    DX,AL
  379.         IN     AL,DX    ; ACKNOWLEDGE INTERRUPT
  380.         MOV    DX,ACOM  ;
  381.         IN     AL,DX    ; GET STATUS
  382.         AND    AL,1
  383.         JE     NODATA
  384.         MOV    DX,ADAT
  385.         IN     AL,DX    ; READ DATA
  386.         MOV    BX,BUFCNT ; GET CURRENT DATA IN BUFFER LENGTH
  387.         MOV    CX,ERRST  ; CHECK IF WE ARE DISCARDING
  388.         JCXZ   NODISC
  389.         CMP    BX,0
  390.         JNE    DISMOR    ; NON 0 MEANS KEEP DISCARDING
  391.         XOR    BX,BX     ; CLEAR DISCARD FLAG
  392.         MOV    ERRST,BX
  393.  
  394. NODISC:
  395.         MOV    CX,BX
  396.         JCXZ   CLEAR
  397.         MOV    BX,INADR ; 8530'S CURRENT ADR
  398.         CMP    BX,SVADR ; IF = THEN BUFFER OVERFLOW
  399.         JE     BOVF
  400. CLEAR:  MOV    BX,INADR
  401.         MOV    BYTE PTR[BX],AL ; SAVE CHAR IN BUFFER
  402.         INC    BUFCNT
  403.         INC    BX
  404.         CMP    BX,OFFSET LADR  ; CHECK IF LAST ADDR IN BUFFER
  405.         JNE    NOTLAS
  406. DISMOR: MOV    BX,OFFSET INBUF ; RESET INPUT POINTER
  407. NOTLAS: MOV    INADR,BX
  408. NODATA: MOV    DX,ACOM
  409.         MOV    AL,38H
  410.         OUT    DX,AL    ; RESET HIGHEST IUS  IN 8530
  411.         IN     AL,DX    ; CHECK IF MORE CHARS IN 8530'S BUFFER
  412.         AND    AL,1
  413.         JNZ    NEXT     ; DUE TO THE OVERHEAD INVOLVED IN INTERRUPTING
  414.         POP    DX       ; IT IS PROBBABLE THAT MORE THAN 1 CHAR
  415.         POP    CX       ; MAY BE IN THE 8530, IT IS CHEAPER IN CLOCK CYCLES
  416.         POP    BX       ; FOR US TO READ ALL CHARS UNTIL THE 8530
  417.         MOV    AL,20H   ; HAS NO MORE.(ALIAS: KILL 2 STONES WITH 1 BIRD)
  418.         OUT    18H,AL  ; RESET TO 8259
  419.         XOR    AX,AX
  420.         MOV    DS,AX
  421.         DEC    DS:BYTE PTR[INTCTR] ; UPDATE INTERRUPT COUNT
  422.         POP    AX
  423.         MOV    SP,CS:[STKSAV+2]
  424.         MOV    SS,SP
  425.         MOV    SP,CS:[STKSAV]    ; RESTORE CALLERS STACK
  426.         POP    DS
  427.         IRET   ;
  428. BOVF:
  429.         MOV    AX,0
  430.         MOV    BUFCNT,AX
  431.         INC    AX
  432.         MOV    ERRST,AX   ; SET DISCARD FLAG
  433.         JMP    NODATA     ; GO BACK
  434.  
  435. ;********************** END OF 8530 ISR *****************************
  436. BUFLEN  EQU    0D000H ; 32K CURRENTLY
  437. INBUF:
  438.         DB      BUFLEN DUP(0); INPUT BUFFER
  439. LADR:
  440. EOMOD:  ; LAST ADDRESS SAVED AFTER TERMINATION
  441.  
  442. BADMSG  DB  ' INVALID OPTION, ENTER "TICOM/T" TO TERMINATE'
  443.         DB  ' OR "TICOM" TO LOAD ',0DH,0AH,'$'
  444. NRMSG   DB  ' TICOM NOT RESIDENT..IGNORED',0DH,0AH,'$'
  445. NTERM   DB  ' TICOM DISABLED, MEMORY FREED',0DH,0AH,'$'
  446. STMSG   DB  ' TI-COM RESIDENT COMMUNICATIONS PACKAGE ',0DH,0AH
  447.         DB  ' UNCOPYRIGHT(U) 1986 DAN MAUS',0DH,0AH
  448.         DB  ' REVISION 1.0 ',0DH,0AH,'$'
  449. LDMSG   DB ' LOADED USING INTERRUPTS 40H(8259 IR0), & 70H(SVC)',0DH,0AH,'$'
  450. INMSG   DB  ' ALREADY RESIDENT ',0DH,0AH,'$'
  451.  
  452.  
  453.  
  454. ;********************* START UP CODE **************************
  455. START:
  456.         PUSH    CS
  457.         POP     DS
  458.         MOV     DX, OFFSET STMSG
  459.         MOV     AH,09H
  460.         INT     21H
  461.         MOV     AL, BYTE PTR ES:[COMNLEN]
  462.         CMP     AL,0
  463.         JE      LOADIT       ; NO PARAMETER MEANS LOAD & KEEP PROCESS
  464.         ;       TERMINATE IF IN CORE OTHERWISE TELL NOT IN CORE
  465.         MOV     AX, WORD PTR ES:[COMNLEN+1]
  466.         CMP     AX,'T/'      ; CHECK FOR /T TO VERIFY TERMINATION
  467.         JNE     BADCMD
  468.         MOV     AH,35H       ; GET VECTOR
  469.         MOV     AL,COMINT
  470.         INT     21H
  471.         CMP     BX,OFFSET COMISR
  472.         JNE     NOTRES       ; NOT LOADED OR VECTOR CORRUPTION
  473.  
  474.         LDS     DX,SVCOLD    ; OLD SVCINT VECTOR
  475.         MOV     AH,25H
  476.         MOV     AL,SVCINT    ; RESTORE SVCINT VECTOR
  477.         INT     21H
  478.         LDS     DX,COMOLD    ; OLD 8530 INTERRUPT VECTOR
  479.         MOV     AL,COMINT
  480.         INT     21H
  481.         MOV     AX,ES
  482.         SUB     AX,10H       ; MAKE PSP ADJUSTMENT
  483.         MOV     ES,AX
  484.         MOV     AH,49H       ; AT THIS POINT ES: SHOULD BE OUR BLOCK
  485.         INT     21H          ; DEALLOCATE
  486.         PUSH    CS
  487.         POP     DS
  488.         MOV     DX, OFFSET NTERM ; NORMAL TERMINATION MESSAGE
  489. EXIT:   MOV     AH,09H
  490.         INT     21H
  491.         MOV     AH,4CH       ; TERMINATE NORMAL(NO KEEP PROCESS)
  492.         INT     21H
  493. BADCMD: MOV     DX, OFFSET BADMSG ; INVALID CONTROL '/T' ONLY VALID
  494.         JMP     EXIT
  495. NOTRES: MOV     DX, OFFSET NRMSG  ; NOT RESIDENT MESSAGE
  496.         JMP     EXIT
  497. INMEM:  MOV     DX, OFFSET INMSG  ; ALREADY RESIDENT ERROR
  498.         JMP     EXIT
  499. LOADIT: ; SET INTERRUPT VECTORS
  500.         ; AND KEEP PROCESS
  501.         PUSH    DS
  502.         POP     ES
  503.         PUSH    ES
  504.         MOV     AL,COMINT
  505.         MOV     AH,35H    ; GET VECTOR
  506.         INT     21H
  507.         CMP     BX,OFFSET COMISR
  508.         JE      INMEM            ; CHECK IF ALREADY IN MEMORY
  509.         MOV     COMOLD,BX
  510.         MOV     BX,ES            ; SAVE OLD SVC VECTOR
  511.         MOV     COMOLD+2,BX
  512.         MOV     AL,SVCINT
  513.         INT     21H
  514.         MOV     SVCOLD,BX
  515.         MOV     BX,ES            ; SAVE OLD COMINT VECTOR
  516.         MOV     SVCOLD+2,BX
  517.         POP     ES
  518.         MOV     AH,25H
  519.         MOV     DX, OFFSET SVCISR  ; SET SVC VECTOR
  520.         MOV     AL, SVCINT
  521.         INT     21H
  522.         MOV     DX, OFFSET COMISR  ; SET COMINT VECTOR
  523.         MOV     AL, COMINT
  524.         INT     21H
  525.         MOV     DX, OFFSET LDMSG
  526.         MOV     AH,09H
  527.         INT     21H
  528.         MOV     AH,31H            ; KEEP PROCESS
  529.         MOV     DX,OFFSET EOMOD   ; LAST LOCATION
  530.         ADD     DX,110H ;         ; ACCOUNT FOR PSP & LAST PARAGRAPH
  531.         SHR     DX,1              ;
  532.         SHR     DX,1
  533.         SHR     DX,1
  534.         SHR     DX,1              ; MAKE INTO PARAGRAPHS
  535.         INT     21H               ; TERMINATE & STAY RESIDENT (2.1 TYPE)
  536. CODE    ENDS
  537.         END
  538.